/**
 * Copyright (C) 2011 GreenSoft S.A.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *        http://www.apache.org/licenses/LICENSE-2.0
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ar.com.greensoft.neosystem.dao.jpa;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.ejb.Stateless;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Order;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;

import org.apache.commons.lang3.StringUtils;

import ar.com.greensoft.neosystem.dao.ObraSocialDao;
import ar.com.greensoft.neosystem.dto.PersonaJuridicaDto;
import ar.com.greensoft.neosystem.model.ObraSocial;
import ar.com.greensoft.neosystem.model.ObraSocial_;
import ar.com.greensoft.neosystem.model.PersonaJuridica_;
import ar.com.greensoft.neosystem.search.SearchFilter;
import ar.com.greensoft.neosystem.search.clientes.ObraSocialSearchFilter;
import ar.com.greensoft.neosystem.util.SearchUtil;

/**
 * Java Persistence API Implementation of PersonaJuridica Data Access Object Pattern
 * @author Jorge E. Villaverde
 * @date 04/10/2011
 * @version 1.1
 */
@Stateless
public class JpaObraSocialDaoImpl 
	extends JpaPersonaDao<ObraSocial, PersonaJuridicaDto>
	implements ObraSocialDao{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	protected Class<ObraSocial> getEntityClazz() {
		return ObraSocial.class;
	}

	@Override
	protected String getFindByCuitQueryName() {
		return ObraSocial.FIND_BY_CUIT_QUERY_NAME;
	}

	@Override
	protected String getFindByTipoNroDocumentoQueryName() {
		return ObraSocial.FIND_BY_TIPO_NRO_DOC_QUERY_NAME;
	}
	
	@Override
	protected Expression<Boolean> createWhereFromSearchFilter(SearchFilter filer,
			Root<ObraSocial> root) {
		if(filer == null || !filer.hasFilter())
			return null;
		
		ObraSocialSearchFilter filter = (ObraSocialSearchFilter)filer;
		CriteriaBuilder criteriaBuilder = getEntityManager().getCriteriaBuilder();
		Predicate predicate = null;

		if(filter.getCuit() != null && filter.getCuit() > 0){
			Predicate predCuit = criteriaBuilder.equal(
					root.get(ObraSocial_.cuit), filter.getCuit());
			predicate = appendAndPredicate(predicate, predCuit);
		}
		
		if(filter.getRazonSocial() != null){
			Predicate predRazonSocial = criteriaBuilder.equal(
					root.get(ObraSocial_.razonSocial), filter.getRazonSocial());
			predicate = appendAndPredicate(predicate, predRazonSocial);			
		}
		
		if(!StringUtils.isBlank(filter.getNombre())){
			String likeString = SearchUtil.likeString(filter.getNombre()).toUpperCase();
			Predicate predNombre = criteriaBuilder.like(criteriaBuilder.upper(root.get(ObraSocial_.nombre)), likeString);
			predicate = appendAndPredicate(predicate, predNombre);			
		}
		
		return predicate;
	}

	@Override
	protected String getFindByNameNamedQuery() {
		return ObraSocial.FIND_BY_NAME_QUERY_NAME;
	}

	@Override
	protected Class<PersonaJuridicaDto> getDtoClazz() {
		return PersonaJuridicaDto.class;
	}

	@Override
	protected Selection<? extends PersonaJuridicaDto> createDtoBuilder(CriteriaBuilder builder, Root<ObraSocial> root) {
		return builder.construct(PersonaJuridicaDto.class,
				root.get(ObraSocial_.id),
				root.get(ObraSocial_.tipoDocumento),
				root.get(ObraSocial_.numeroDocumento),
				root.get(ObraSocial_.cuit),
				root.get(ObraSocial_.nombre),
				root.get(ObraSocial_.razonSocial));
	}

	@Override
	protected Map<String, Expression<?>> getExpressionMap(Root<ObraSocial> root) {
		if(expressionMap == null){
			expressionMap = new HashMap<String, Expression<?>>();
			expressionMap.put("tipoDocumento", root.get(PersonaJuridica_.tipoDocumento));
			expressionMap.put("numeroDocumento", root.get(PersonaJuridica_.numeroDocumento));
			expressionMap.put("cuit", root.get(PersonaJuridica_.cuit));
			expressionMap.put("nombre", root.get(PersonaJuridica_.nombre));
			expressionMap.put("razonSocial", root.get(PersonaJuridica_.razonSocial));
		}
		return expressionMap;
	}
	
	@Override
	protected List<Order> createOrders(Root<ObraSocial> root) {
		CriteriaBuilder builder = getEntityManager().getCriteriaBuilder();
		List<Order> orders = new ArrayList<Order>();
		orders.add(builder.asc(root.get(ObraSocial_.cuit)));
		orders.add(builder.asc(root.get(ObraSocial_.nombre)));
		orders.add(builder.asc(root.get(ObraSocial_.razonSocial)));
		return orders;
	}
	
}
